package com.qjc.handler;


import com.qjc.entity.Result;
import com.qjc.enums.ResultModelEnum;
import com.qjc.exception.AbstractBusinessException;
import com.qjc.util.MessageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;


/**
 * @author Kevin
 * @version 1.0
 * @description: 全局异常处理类
 * @date 2021/7/19 15:07
 */
@RestControllerAdvice
@SuppressWarnings("all")
@ConditionalOnClass({javax.servlet.ServletException.class})
@Slf4j
public class GloabalExceptionHanlder {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @ExceptionHandler(AbstractBusinessException.class)
    public Result<String> AbstractBusinessException(Exception exception) {
        log.error("发生业务异常", exception);
        return this.handleError(exception);
    }

    @ExceptionHandler(Exception.class)
    public Result<String> customException(Exception exception) {
        log.error("发生异常", exception);
        return this.handleError(exception);
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result<String> missingParamException(MissingServletRequestParameterException missingParam) {
        log.error("发生异常", missingParam);
        return Result.exception(
                String.format("缺少参数：[ %s(%s) ]", missingParam.getParameterName(), missingParam.getParameterType())
        );
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result<String> missingBodyException(HttpMessageNotReadableException missingBody) {
        log.error("发生异常", missingBody);
        return Result.exception("请求参数格式有误");
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handle(MethodArgumentNotValidException exception, HttpServletRequest request) {
        BindingResult errors = exception.getBindingResult();
        return Result.failed(errors.getFieldError().getDefaultMessage());
    }

    private Result handleError(Throwable ex) {
        if (ex instanceof AbstractBusinessException) {
            String errMsg = MessageUtils.get(((AbstractBusinessException) ex).getErrCode());
            if (StringUtils.isEmpty(errMsg)) {
                return Result.failed(((AbstractBusinessException) ex).getErrCode(), ((AbstractBusinessException) ex).getErrMsg());
            } else {
                return Result.failed(((AbstractBusinessException) ex).getErrCode(), errMsg);
            }
        } else {
            //applicationEventPublisher.publishEvent(new FlyingBootMessageEvent(ex));
            return Result.failed(ResultModelEnum.GLOBAL_EXCEPTION.getMessage());
        }
    }

}
